﻿#pragma once
#ifndef CONTROL_H_
#define CONTROL_H_

#include "BaseInc_BlueprintScript.h"
#include "IEventListener.h"
#include "Delegate.h"
#include "InputHandler.h"
#include "TString.h"
#include "Layout.h"

class Control;
#define DEDCLAR_EH_MOUSE EventHandler<Control,MouseMoveEventArgs> mouseMove; \
				EventHandler<Control,MouseButtonEventArgs> mouseDown;	\
				EventHandler<Control,MouseButtonEventArgs> mouseUp;
#define DECLAR_EH_KEYBOARD EventHandler<Control, KeyEventArgs> keyDownEvent;	\
				EventHandler<Control, KeyEventArgs> keyUpEvent;


struct ControlEvent {
	DEDCLAR_EH_MOUSE
		DECLAR_EH_KEYBOARD
};
class TiXmlElement;
class Control :public BlueprintScriptLibrary::Object, public IEventListener
{
public:
	using ControlPtr = std::shared_ptr<Control>;
	Control() {}
	virtual void Create(class Window* parent, vec2 pos, vec2 size, UINT32 id) {
		this->pos = pos;
		this->size = size;
		this->id = id;
		this->rootWindow = parent;
	}
	virtual tstring GetClassName() { return _T("Control"); }
	virtual bool OnInit() { return true; }
	virtual void OnDestroy() {}
	void Draw() { if (bVisible) OnDraw(); }
	virtual void OnDraw() { }
	virtual void Resize(Vec2vbi si) {}
	virtual void Resize(int w,int h) {}
	virtual void OnSizeChanged(Vec2vbi newSize) {}
	virtual bool HitTest(vec2 pos);	// 
	virtual bool SetAttribute(const char* attrName, const char* attrVal);
	virtual void ParseXmlElement( TiXmlElement* ele) {}
	void DoParseXmlElement(TiXmlElement* ele); // usually ctrl will often call it if type is container 
	virtual void FocusControl(bool b) { bFocused = b; }
	virtual void onMouseButtonUp(int button, int x, int y) {
		MouseButtonEventArgs arg;
		arg.button = button;
		arg.x = x;
		arg.y = y;
		events.mouseUp.Invoke(this, arg);
	}
	virtual Control* GetHitControl(int x,int y);
	BlueprintScriptLibrary::Class* GetClass();
	Vec2vbi pos;		//λ  
	Vec2vbi size;		//  С
	Vec4vbi margin;		//    
	Vec4vbi border;		// ߿ 
	std::vector<std::pair<tstring, Control*>> childs;
	//vector<Control*> childs;
	ControlPtr parent;
	VarBaseInt zIndex{ 0 };
	VarBaseInt id;
	VarBaseString name;
	bool bFocused{ false };
	bool bVisible{true};
	Window* rootWindow = nullptr;
	// ¼ 
	ControlEvent events;
	HorizenAlign halign{ HorizenAlign::Left};
	VerticalAlign valign{ VerticalAlign::Top};
protected:
	void DrawBorder();
};

RegisterBlueprintClass(Control)

#endif // !1